using Nop.Core.Domain.Discounts;
using Nop.Plugin.DiscountRules.Customers.Models;
using Nop.Plugin.DiscountRules.Customers.Services;
using Nop.Services.Customers;
using Nop.Services.Discounts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Nop.Plugin.DiscountRules.Customers.Controllers
{
	public class DiscountRulesCustomersController : Controller
	{
		private readonly IDiscountService _discountService;
		private readonly ICustomerService _customerService;
		private readonly IRequirementCustomerService _requirementCustomerService;

		public DiscountRulesCustomersController(IDiscountService disctountService, ICustomerService customerService,
			IRequirementCustomerService discountCustomerService)
		{
			_discountService = disctountService;
			_customerService = customerService;
			_requirementCustomerService = discountCustomerService;
		}

		/// <summary>
		/// Shows customers who are applied the discount requirement
		/// </summary>
		/// <param name="discountId"></param>
		/// <param name="discountRequirementId"></param>
		/// <returns></returns>
		public ActionResult Configure(int discountId, int? discountRequirementId)
		{
			var model = new CustomerListModel();
			if(discountRequirementId.HasValue)
			{
				var customers = _requirementCustomerService.GetRequirementCustomers(discountRequirementId.Value, null)
					.Select(rc=>rc.Customer)
					.Select(c=>new CustomerModel{ 
						CustomerId = c.Id, Email = c.Email, FullName = c.GetFullName()});
				model.AppliedCustomers = customers;
				model.RequirementId = discountRequirementId.Value;				
			}
			model.DiscountId = discountId;
			return View("Nop.Plugin.DiscountRules.Customers.Views.DiscountRulesCustomers.Configure", model);
		}

		[HttpPost]
		public ActionResult RemoveCustomers(int discountId, int discountRequirementId, int[] customerIds)
		{
            if(discountId != 0 && discountRequirementId != 0 && customerIds != null && customerIds.Length > 0)
			{
				var customers = _requirementCustomerService.GetRequirementCustomers(discountRequirementId, customerIds);
				if(customers.Count()>0)
					customers.ToList()
						     .ForEach(c => _requirementCustomerService.RemoveCustomerFromRequirement(c.CustomerId, c.RequirementId));
			}
			return null;
		}

		/// <summary>
		/// Add new customers to the requirement
		/// </summary>
		/// <param name="discountId"></param>
		/// <param name="discountRequirementId"></param>
		/// <param name="customerIds"></param>
		/// <returns></returns>
		[HttpPost]
        public ActionResult Configure(int discountId, int? discountRequirementId, int[] customerIds)
		{
			var discount = _discountService.GetDiscountById(discountId);
			if (discount == null)
				throw new ArgumentException("Discount could not be loaded");

			DiscountRequirement discountRequirement = null;
			if (discountRequirementId.HasValue)
				discountRequirement = discount.DiscountRequirements.Where(dr => dr.Id == discountRequirementId.Value).FirstOrDefault();

			if (discountRequirement != null)
			{
				//update existing rule
				var customers = _requirementCustomerService.GetRequirementCustomers(discountRequirement.Id).ToDictionary(c => c.CustomerId);
				Array.ForEach(customerIds, id =>
				{
					if (!customers.ContainsKey(id))
						_requirementCustomerService.AddCustomerToRequirement(id, discountRequirement.Id);
				});
			}
			else
			{
				//save new rule
				discountRequirement = new DiscountRequirement()
				{
					DiscountRequirementRuleSystemName = "DiscountRequirement.MustAssignToCustomers"
				};
				discount.DiscountRequirements.Add(discountRequirement);
				_discountService.UpdateDiscount(discount);

				if(customerIds!=null)
				{
					Array.ForEach(customerIds, id =>
					{
						_requirementCustomerService.AddCustomerToRequirement(id, discountRequirement.Id);
					});					
				}
			}
			return Json(new { Result = true, NewRequirementId = discountRequirement.Id }, JsonRequestBehavior.AllowGet);
		}
	}
}
